﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Sdari.Api.Services;
using Sdari.Core.Controllers;
using System;
using System.Collections.Generic;
using System.Net;

namespace Sdari.Api.Gateway.Controllers
{
    [Route("Token/[action]")]
    public class TokenController : SdariDtmController
    {
        private const string Forbidden = "forbidden";
        private const string AccessFailed = "access failed";
        private const string InvalidParameters = "invalid parameters";
        private const string VerifyFailed = "verify failed";
        private const string NoKeyFound = "no key found";
        private const string InvalidIp = "Ip adress is not valid";

        private readonly ITokenService _tokenSvc;
        private readonly ILogger<TokenController> _logger;

        public TokenController(ITokenService tokenService, ILogger<TokenController> logger)
        {
            _tokenSvc = tokenService;
            _logger = logger;
        }

        [HttpPost]
        public ActionResult GetToken(string clientId, string secret)
        {
            if (!string.IsNullOrEmpty(clientId))
            {
                var result = _tokenSvc.GetToken(clientId, secret);
                //没有值说明认证失败
                if (result == null)
                    return Unauthorized(Forbidden, AccessFailed);
                //成功返回
                var (token, expire) = result.Value;
                return Ok(new { token, expire });
            }
            return BadRequest(InvalidParameters);
        }

        /// <summary>
        /// Nginx默认使用get来访问auth，需要可以配置ngnix的proxy_method为post
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ActionResult VerifyToken()
        {
            var url = Request.Headers["X-Original-Uri"];
            var list = new List<(string, string)>();
            if (IPAddress.TryParse(Request.Headers["X-Original-Ip"], out var ip))
            {
                list.Add((ip.ToString(), WhiteListType.Ip));
                if (_tokenSvc.WhiteListCheck(url, list, ip.GetAddressBytes()))
                {//白名单内，直接通过
                    return Ok();
                }
                else
                {//不在白名单内，验证token
                    var token = Request.Headers["AccessKey"];
                    if (Guid.TryParse(token, out var uid))
                    {//带有AccessKey
                        if (_tokenSvc.VerifyToken(uid, url, ip.GetAddressBytes()))
                        {
                            return Ok();
                        }
                        else
                        {//验证失败，返回错误
                            //只有401可以回传header
                            return Unauthorized(Forbidden, VerifyFailed);
                        }
                    }
                    else
                    {//没带AccessKey，返回错误
                        //只有401可以回传header
                        return Unauthorized(Forbidden, NoKeyFound);
                    }
                }
            }
            else
            {
                return Unauthorized(Forbidden, InvalidIp);
            }
        }
    }
}
